package com.wande.dataplatform.filecollection.security;

import cn.hutool.json.JSONUtil;
import com.wande.common.satoken.utils.LoginHelper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * 审计日志服务
 * 记录文件采集相关的操作审计日志
 *
 * @author wande
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class AuditLogService {

    private final RedisTemplate<String, Object> redisTemplate;

    private static final String AUDIT_LOG_PREFIX = "file-collection:audit:";
    private static final long AUDIT_LOG_EXPIRE_DAYS = 90;
    private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

    /**
     * 记录审计日志
     *
     * @param operation 操作类型
     * @param resourceType 资源类型
     * @param resourceId 资源ID
     * @param details 详细信息
     */
    public void log(String operation, String resourceType, Long resourceId, Map<String, Object> details) {
        try {
            Map<String, Object> auditLog = new HashMap<>();
            auditLog.put("operation", operation);
            auditLog.put("resourceType", resourceType);
            auditLog.put("resourceId", resourceId);
            auditLog.put("details", details);
            auditLog.put("timestamp", LocalDateTime.now().format(FORMATTER));
            
            // 获取当前用户信息
            try {
                Long userId = LoginHelper.getUserId();
                String username = LoginHelper.getUsername();
                auditLog.put("userId", userId);
                auditLog.put("username", username);
            } catch (Exception e) {
                auditLog.put("userId", null);
                auditLog.put("username", "system");
            }
            
            // 生成日志键
            String key = AUDIT_LOG_PREFIX + System.currentTimeMillis();
            
            // 存储到Redis
            redisTemplate.opsForValue().set(key, JSONUtil.toJsonStr(auditLog), 
                AUDIT_LOG_EXPIRE_DAYS, TimeUnit.DAYS);
            
            log.info("Audit log recorded: operation={}, resourceType={}, resourceId={}", 
                operation, resourceType, resourceId);
            
        } catch (Exception e) {
            log.error("Failed to record audit log", e);
        }
    }

    /**
     * 记录采集规则操作
     */
    public void logRuleOperation(String operation, Long ruleId, Map<String, Object> details) {
        log(operation, "COLLECTION_RULE", ruleId, details);
    }

    /**
     * 记录映射规则操作
     */
    public void logMappingOperation(String operation, Long mappingId, Map<String, Object> details) {
        log(operation, "MAPPING_RULE", mappingId, details);
    }

    /**
     * 记录任务操作
     */
    public void logTaskOperation(String operation, Long taskId, Map<String, Object> details) {
        log(operation, "COLLECTION_TASK", taskId, details);
    }

    /**
     * 记录文件操作
     */
    public void logFileOperation(String operation, Long fileId, Map<String, Object> details) {
        log(operation, "FILE_RECORD", fileId, details);
    }

    /**
     * 记录文件上传
     */
    public void logFileUpload(String fileName, long fileSize, String fileType) {
        Map<String, Object> details = new HashMap<>();
        details.put("fileName", fileName);
        details.put("fileSize", fileSize);
        details.put("fileType", fileType);
        log("FILE_UPLOAD", "FILE", null, details);
    }

    /**
     * 记录文件下载
     */
    public void logFileDownload(Long fileId, String fileName) {
        Map<String, Object> details = new HashMap<>();
        details.put("fileName", fileName);
        log("FILE_DOWNLOAD", "FILE", fileId, details);
    }

    /**
     * 记录文件删除
     */
    public void logFileDelete(Long fileId, String fileName) {
        Map<String, Object> details = new HashMap<>();
        details.put("fileName", fileName);
        log("FILE_DELETE", "FILE", fileId, details);
    }

    /**
     * 记录数据访问
     */
    public void logDataAccess(String database, String table, String operation) {
        Map<String, Object> details = new HashMap<>();
        details.put("database", database);
        details.put("table", table);
        details.put("operation", operation);
        log("DATA_ACCESS", "DATABASE", null, details);
    }

    /**
     * 记录安全事件
     */
    public void logSecurityEvent(String eventType, String description, Map<String, Object> details) {
        if (details == null) {
            details = new HashMap<>();
        }
        details.put("eventType", eventType);
        details.put("description", description);
        log("SECURITY_EVENT", "SECURITY", null, details);
    }
}
